<script>
    import TabNav from './tab-nav';

    export default {
        name: 'ElTabs',

        components: {
            TabNav
        },

        props: {
            type: String,
            activeName: String,
            closable: Boolean,
            addable: Boolean,
            value: {},
            editable: Boolean,
            tabPosition: {
                type: String,
                default: 'top'
            },
            beforeLeave: Function,
            stretch: Boolean
        },

        provide() {
            return {
                rootTabs: this
            };
        },

        data() {
            return {
                currentName: this.value || this.activeName,
                panes: []
            };
        },

        watch: {
            activeName(value) {
                this.setCurrentName(value);
            },
            value(value) {
                this.setCurrentName(value);
            },
            currentName(value) {
                if (this.$refs.nav) {
                    this.$nextTick(() => {
                        this.$refs.nav.$nextTick(_ => {
                            this.$refs.nav.scrollToActiveTab();
                        });
                    });
                }
            }
        },

        methods: {
            calcPaneInstances(isForceUpdate = false) {
                if (this.$slots.default) {
                    const paneSlots = this.$slots.default.filter(vnode => vnode.tag &&
                        vnode.componentOptions && vnode.componentOptions.Ctor.options.name === 'ElTabPane');
                    // update indeed
                    const panes = paneSlots.map(({componentInstance}) => componentInstance);
                    const panesChanged = !(panes.length === this.panes.length && panes.every((pane, index) => pane === this.panes[index]));
                    if (isForceUpdate || panesChanged) {
                        this.panes = panes;
                    }
                } else if (this.panes.length !== 0) {
                    this.panes = [];
                }
            },
            handleTabClick(tab, tabName, event) {
                if (tab.disabled) return;
                this.setCurrentName(tabName);
                this.$emit('tab-click', tab, event);
            },
            handleTabRemove(pane, ev) {
                if (pane.disabled) return;
                ev.stopPropagation();
                this.$emit('edit', pane.name, 'remove');
                this.$emit('tab-remove', pane.name);
            },
            handleTabAdd() {
                this.$emit('edit', null, 'add');
                this.$emit('tab-add');
            },
            setCurrentName(value) {
                const changeCurrentName = () => {
                    this.currentName = value;
                    this.$emit('input', value);
                };
                if (this.currentName !== value && this.beforeLeave) {
                    const before = this.beforeLeave(value, this.currentName);
                    if (before && before.then) {
                        before
                            .then(() => {
                                changeCurrentName();
                                this.$refs.nav && this.$refs.nav.removeFocus();
                            }, () => {
                                // https://github.com/ElemeFE/element/pull/14816
                                // ignore promise rejection in `before-leave` hook
                            });
                    } else if (before !== false) {
                        changeCurrentName();
                    }
                } else {
                    changeCurrentName();
                }
            }
        },

        render(h) {
            let {
                type,
                handleTabClick,
                handleTabRemove,
                handleTabAdd,
                currentName,
                panes,
                editable,
                addable,
                tabPosition,
                stretch
            } = this;

            const newButton = editable || addable
                ? (
                < span
                class = "el-tabs__new-tab"
            on - click = {handleTabAdd}
            tabindex = "0"
            on - keydown = {(ev)
        =>
            {
                if (ev.keyCode === 13) {
                    handleTabAdd();
                }
            }
        }
        >
        <
            i
        class
            = "el-icon-plus" > < /i>
                < /span>
        )
        :
            null;

            const navData = {
                props: {
                    currentName,
                    onTabClick: handleTabClick,
                    onTabRemove: handleTabRemove,
                    editable,
                    type,
                    panes,
                    stretch
                },
                ref: 'nav'
            };
            const header = (
                < div
        class
            = {['el-tabs__header',`is-${tabPosition}`
        ]
        }>
            {
                newButton
            }
        <
            tab - nav
            { ...
                navData
            }
        ><
            /tab-nav>
            < /div>
        )
            ;
            const panels = (
                < div
        class
            = "el-tabs__content" >
                {this.$slots.default
        }
        <
            /div>
        )
            ;

            return (
                < div
        class
            = {
            {
                'el-tabs'
            :
                true,
                    'el-tabs--card'
            :
                type === 'card',
                    [`el-tabs--${tabPosition}`]
            :
                true,
                    'el-tabs--border-card'
            :
                type === 'border-card'
            }
        }>
            {
                tabPosition !== 'bottom' ? [header, panels] : [panels, header]
            }
        <
            /div>
        )
            ;
        },

        created() {
            if (!this.currentName) {
                this.setCurrentName('0');
            }

            this.$on('tab-nav-update', this.calcPaneInstances.bind(null, true));
        },

        mounted() {
            this.calcPaneInstances();
        },

        updated() {
            this.calcPaneInstances();
        }
    };
</script>
